#include "server_network.h"

server_network::server_network() {

}

server_network::~server_network() {
}

int server_network::listen(Uint16 port) {
	IPaddress ip;

	resolve(NULL, port, &ip);
	if ((this->conn_list[0] = SDLNet_TCP_Open(&ip)) == NULL) {
		log_config.print(PACMEN_LOG_ERROR, PACMEN_LOG_FILEATTRIBUTE, "Error calling SDLNet_TCP_Open()\n");
		return EXIT_FAILURE;
	}
	SDLNet_TCP_AddSocket(this->sockset, this->conn_list[0]);
	this->status = NET_LISTENING;
	this->conn_count = 1;
	return EXIT_SUCCESS;
}

int server_network::accept() {
	if (SDLNet_SocketReady(this->conn_list[0])) {
		this->conn_list[this->conn_count] = SDLNet_TCP_Accept(this->conn_list[0]);
		SDLNet_TCP_AddSocket(this->sockset, this->conn_list[this->conn_count++]);
		return EXIT_SUCCESS;
	}

	return EXIT_FAILURE;
}

int server_network::close(int socket_num) {
	if (!this->conn_list[socket_num])
		return EXIT_FAILURE;

	SDLNet_TCP_Close(this->conn_list[socket_num]);
	SDLNet_TCP_DelSocket(this->sockset, this->conn_list[socket_num]);
	this->conn_list[socket_num] = NULL;
	if (socket_num == this->conn_count - 1)
		this->conn_count--;
	return EXIT_SUCCESS;
}

int server_network::receive(void *buf, size_t max_size, TCPsocket *socket, size_t *bytes) {
	for (int i=1; i<this->conn_count; i++) {
		if (!SDLNet_SocketReady(this->conn_list[i]))
			continue;

		if ((*bytes = SDLNet_TCP_Recv(this->conn_list[i], buf, max_size)) <= 0) {
			log_config.print(PACMEN_LOG_ERROR, PACMEN_LOG_FILEATTRIBUTE, "Error calling SDLNet_TCP_Recv()\n");
			this->close(i);
			return EXIT_FAILURE;
		}
		return EXIT_SUCCESS;
	}

	return EXIT_FAILURE;
}

int server_network::broadcast(void *buf, size_t size) {
	for (int i=1; i<this->conn_count; i++) {
		if (SDLNet_TCP_Send(this->conn_list[i], buf, size) <= 0) {
			log_config.print(PACMEN_LOG_ERROR, PACMEN_LOG_FILEATTRIBUTE, "Error calling SDLNet_TCP_Recv()\n");
			this->close(i);
		}
	}

	return EXIT_SUCCESS;
}

